package leetcode.other.comon;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class OtherUtils {

    /**
     * 已知函数signFunc(x) 将会根据 x 的正负返回特定值：
     * 如果 x 是正数，返回 1 。
     * 如果 x 是负数，返回 -1 。
     * 如果 x 是等于 0 ，返回 0 。
     * 给你一个整数数组 nums 。令 product 为数组 nums 中所有元素值的乘积。
     * <p>
     * 返回 signFunc(product) 。
     *
     * @param nums
     * @return
     */
    public static int arraySign(int[] nums) {
        int numOfNeg = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == 0) {
                return 0;
            }
            if (nums[i] < 0) {
                numOfNeg++;
            }
        }
        if (numOfNeg % 2 == 0) {
            return 1;
        } else {
            return -1;
        }
    }

    public static boolean isPalindrome(int x) {
        if (x < 0) {
            return false;
        }
        if (x == 0) {
            return true;
        }
        int[] nums = new int[32];
        int index = 0;
        while (x > 0) {
            nums[index] = x % 10;
            index++;
            x = x / 10;
        }
        int left = 0;
        int right = index - 1;
        while (left <= right) {
            if (nums[left] != nums[right]) {
                return false;
            }
            left++;
            right--;
        }
        return true;
    }

    public static String intToRoman(int num) {
        if (num <= 0) {
            return "";
        }
        String result = "";
        String[] romans = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
        int[] numbers = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
        int curIndex = 0;
        while (num > 0) {
            if (num >= numbers[curIndex]) {
                result = result + romans[curIndex];
                num = num - numbers[curIndex];
            } else {
                curIndex++;
            }
        }
        return result;
    }

    public static int romanToInt(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }
        int result = 0;
        char[] array = s.toCharArray();
        for (int i = 0; i < array.length; i++) {
            if (array[i] == 'M') {
                result = result + 1000;
            }
            if (array[i] == 'D') {
                result = result + 500;
            }
            if (array[i] == 'C') {
                if (i + 1 < array.length && array[i + 1] == 'M') {
                    result = result + 900;
                    i++;
                    continue;
                }
                if (i + 1 < array.length && array[i + 1] == 'D') {
                    result = result + 400;
                    i++;
                    continue;
                }
                result = result + 100;
            }
            if (array[i] == 'L') {
                result = result + 50;
            }
            if (array[i] == 'X') {
                if (i + 1 < array.length && array[i + 1] == 'C') {
                    result = result + 90;
                    i++;
                    continue;
                }
                if (i + 1 < array.length && array[i + 1] == 'L') {
                    result = result + 40;
                    i++;
                    continue;
                }
                result = result + 10;
            }
            if (array[i] == 'V') {
                result = result + 5;
            }
            if (array[i] == 'I') {
                if (i + 1 < array.length && array[i + 1] == 'X') {
                    result = result + 9;
                    i++;
                    continue;
                }
                if (i + 1 < array.length && array[i + 1] == 'V') {
                    result = result + 4;
                    i++;
                    continue;
                }
                result = result + 1;
            }
        }
        return result;
    }

    public static int reverse(int x) {
        int result = 0;
        while (x != 0) {
            if (result < Integer.MIN_VALUE / 10 || result > Integer.MAX_VALUE / 10) {
                return 0;
            }
            int digit = x % 10;
            x = x / 10;
            result = result * 10 + digit;
        }
        return result;
    }

    public static List<List<Integer>> generate(int numRows) {
        List<List<Integer>> result = new ArrayList<>();
        if (numRows <= 0) {
            return result;
        }
        if (numRows == 1) {
            List<Integer> line = new ArrayList<>();
            line.add(1);
            result.add(line);
            return result;
        }
        Integer[] curLine;
        Integer[] lastLine = null;
        for (int i = 1; i <= numRows; i++) {
            curLine = new Integer[i];
            if (i == 1) {
                curLine[0] = 1;
                List<Integer> curList = Arrays.asList(curLine);
                result.add(curList);
                lastLine = curLine;
                continue;
            }
            curLine[0] = 1;
            curLine[curLine.length - 1] = 1;
            for (int j = 1; j <= curLine.length - 2; j++) {
                curLine[j] = lastLine[j - 1] + lastLine[j];
            }
            List<Integer> curList = Arrays.asList(curLine);
            result.add(curList);
            lastLine = curLine;
        }
        return result;
    }

    public static List<Integer> getRow(int rowIndex) {
        List<Integer> result = new ArrayList<>();
        if (rowIndex < 0) {
            return result;
        }
        if (rowIndex == 0) {
            result.add(1);
            return result;
        }
        Integer[] curLine = null;
        Integer[] lastLine = null;
        for (int i = 0; i <= rowIndex; i++) {
            curLine = new Integer[i + 1];
            if (i == 0) {
                curLine[0] = 1;
                lastLine = curLine;
                continue;
            }
            curLine[0] = 1;
            curLine[curLine.length - 1] = 1;
            for (int j = 1; j <= curLine.length - 2; j++) {
                curLine[j] = lastLine[j - 1] + lastLine[j];
            }
            lastLine = curLine;
        }
        return Arrays.asList(curLine);
    }

    public static int countDaysTogether(String arriveAlice, String leaveAlice, String arriveBob, String leaveBob) {

        int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int[] prefix = new int[12];
        prefix[0] = monthDays[0];
        for (int i = 1; i < 12; i++) {
            prefix[i] = prefix[i - 1] + monthDays[i];
        }

        int arriveAliceDay = convertDateToNumber(arriveAlice, prefix);
        int leaveAliceDay = convertDateToNumber(leaveAlice, prefix);
        int arriveBobDay = convertDateToNumber(arriveBob, prefix);
        int leaveBobDay = convertDateToNumber(leaveBob, prefix);

        return Math.max(0, Math.min(leaveAliceDay, leaveBobDay) - Math.max(arriveAliceDay, arriveBobDay) + 1);

//        // 两个人没有交集
//        if (leaveAliceDay < arriveBobDay || leaveBobDay < arriveAliceDay) {
//            return 0;
//        }
//        // bob是alice的子集
//        if (arriveAliceDay <= arriveBobDay && leaveAliceDay >= leaveBobDay) {
//            return leaveBobDay - arriveBobDay + 1;
//        }
//        // alice是bos的子集
//        if (arriveBobDay <= arriveAliceDay && leaveBobDay >= leaveAliceDay) {
//            return leaveAliceDay - arriveAliceDay + 1;
//        }
//        // alice的末尾与bob的开头重合
//        if (arriveAliceDay <= arriveBobDay && arriveBobDay <= leaveAliceDay && leaveAliceDay <= leaveBobDay) {
//            return leaveAliceDay - arriveBobDay + 1;
//        }
//        // bob的末尾与alice的开头重合
//        if (arriveBobDay <= arriveAliceDay && arriveAliceDay <= leaveBobDay && leaveBobDay <= leaveAliceDay) {
//            return leaveBobDay - arriveAliceDay + 1;
//        }
//        return 0;
    }

    private static int convertDateToNumber(String date, int[] prefix) {
        String[] split = date.split("-");
        int month = Integer.parseInt(split[0]);
        int day = Integer.parseInt(split[1]);
        int result = 0;
        if (month > 1) {
            result += prefix[month - 2];
        }
        result += day;
        return result;
    }
}
